# API文档和接口增强功能
from rest_framework import viewsets, permissions, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.authentication import TokenAuthentication, SessionAuthentication
from rest_framework.throttling import UserRateThrottle, AnonRateThrottle
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.filters import SearchFilter, OrderingFilter
from drf_spectacular.utils import extend_schema, extend_schema_view, OpenApiParameter
from drf_spectacular.types import OpenApiTypes
import logging

from .models import Asset, AssetCategory, Department, MaintenanceRecord, Consumable, Supplier, Contract
from .serializers_enhanced import (
    AssetDetailSerializer, AssetListSerializer, AssetCreateSerializer,
    MaintenanceRecordSerializer, ConsumableSerializer, SupplierSerializer, ContractSerializer
)

logger = logging.getLogger(__name__)


class CustomUserRateThrottle(UserRateThrottle):
    """自定义用户限流"""
    scope = 'user'


class CustomAnonRateThrottle(AnonRateThrottle):
    """自定义匿名用户限流"""
    scope = 'anon'


@extend_schema_view(
    list=extend_schema(
        summary="获取资产列表",
        description="获取资产列表，支持分页、搜索、过滤和排序",
        parameters=[
            OpenApiParameter(
                name='search',
                type=OpenApiTypes.STR,
                location=OpenApiParameter.QUERY,
                description='搜索关键词（资产名称、编号）'
            ),
            OpenApiParameter(
                name='category',
                type=OpenApiTypes.INT,
                location=OpenApiParameter.QUERY,
                description='资产类别ID'
            ),
            OpenApiParameter(
                name='department',
                type=OpenApiTypes.INT,
                location=OpenApiParameter.QUERY,
                description='部门ID'
            ),
            OpenApiParameter(
                name='status',
                type=OpenApiTypes.STR,
                location=OpenApiParameter.QUERY,
                description='资产状态'
            ),
            OpenApiParameter(
                name='ordering',
                type=OpenApiTypes.STR,
                location=OpenApiParameter.QUERY,
                description='排序字段（可选：name, asset_number, purchase_date, purchase_price）'
            ),
        ],
        tags=['资产管理']
    ),
    create=extend_schema(
        summary="创建新资产",
        description="创建一个新的资产记录",
        tags=['资产管理']
    ),
    retrieve=extend_schema(
        summary="获取资产详情",
        description="根据ID获取资产的详细信息",
        tags=['资产管理']
    ),
    update=extend_schema(
        summary="更新资产信息",
        description="更新指定资产的完整信息",
        tags=['资产管理']
    ),
    partial_update=extend_schema(
        summary="部分更新资产信息",
        description="部分更新指定资产的信息",
        tags=['资产管理']
    ),
    destroy=extend_schema(
        summary="删除资产",
        description="删除指定的资产记录",
        tags=['资产管理']
    ),
)
class EnhancedAssetViewSet(viewsets.ModelViewSet):
    """增强的资产API视图集"""
    
    queryset = Asset.objects.select_related('category', 'department', 'location', 'supplier').all()
    permission_classes = [permissions.IsAuthenticated]
    authentication_classes = [TokenAuthentication, SessionAuthentication]
    throttle_classes = [CustomUserRateThrottle]
    
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['category', 'department', 'status', 'supplier']
    search_fields = ['name', 'asset_number', 'description']
    ordering_fields = ['name', 'asset_number', 'purchase_date', 'purchase_price', 'created_at']
    ordering = ['-created_at']
    
    def get_serializer_class(self):
        """根据操作类型返回不同的序列化器"""
        if self.action == 'list':
            return AssetListSerializer
        elif self.action == 'create':
            return AssetCreateSerializer
        else:
            return AssetDetailSerializer
    
    def get_queryset(self):
        """根据用户权限过滤查询集"""
        queryset = super().get_queryset()
        
        # 如果不是管理员，只能查看自己部门的资产
        if not self.request.user.is_staff:
            user_department = getattr(self.request.user, 'department', None)
            if user_department:
                queryset = queryset.filter(department=user_department)
        
        return queryset
    
    @extend_schema(
        summary="获取资产统计信息",
        description="获取资产的统计信息，包括总数、各状态数量等",
        responses={200: {
            'type': 'object',
            'properties': {
                'total_count': {'type': 'integer', 'description': '总资产数'},
                'status_counts': {'type': 'object', 'description': '各状态资产数量'},
                'category_counts': {'type': 'object', 'description': '各类别资产数量'},
                'total_value': {'type': 'number', 'description': '资产总价值'},
            }
        }},
        tags=['资产管理']
    )
    @action(detail=False, methods=['get'])
    def statistics(self, request):
        """获取资产统计信息"""
        queryset = self.get_queryset()
        
        # 基础统计
        total_count = queryset.count()
        
        # 状态统计
        status_counts = {}
        for status_choice in Asset.STATUS_CHOICES:
            status_code = status_choice[0]
            count = queryset.filter(status=status_code).count()
            status_counts[status_code] = count
        
        # 类别统计
        category_counts = {}
        categories = AssetCategory.objects.all()
        for category in categories:
            count = queryset.filter(category=category).count()
            category_counts[category.name] = count
        
        # 价值统计
        total_value = sum([asset.purchase_price or 0 for asset in queryset])
        
        return Response({
            'total_count': total_count,
            'status_counts': status_counts,
            'category_counts': category_counts,
            'total_value': float(total_value),
        })
    
    @extend_schema(
        summary="批量更新资产状态",
        description="批量更新多个资产的状态",
        request={
            'type': 'object',
            'properties': {
                'asset_ids': {
                    'type': 'array',
                    'items': {'type': 'integer'},
                    'description': '资产ID列表'
                },
                'status': {
                    'type': 'string',
                    'description': '新状态'
                }
            },
            'required': ['asset_ids', 'status']
        },
        responses={200: {
            'type': 'object',
            'properties': {
                'success': {'type': 'boolean'},
                'updated_count': {'type': 'integer'},
                'message': {'type': 'string'}
            }
        }},
        tags=['资产管理']
    )
    @action(detail=False, methods=['post'])
    def batch_update_status(self, request):
        """批量更新资产状态"""
        asset_ids = request.data.get('asset_ids', [])
        new_status = request.data.get('status')
        
        if not asset_ids or not new_status:
            return Response({
                'success': False,
                'message': '缺少必要参数'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 验证状态值
        valid_statuses = [choice[0] for choice in Asset.STATUS_CHOICES]
        if new_status not in valid_statuses:
            return Response({
                'success': False,
                'message': '无效的状态值'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 批量更新
        queryset = self.get_queryset().filter(id__in=asset_ids)
        updated_count = queryset.update(status=new_status)
        
        return Response({
            'success': True,
            'updated_count': updated_count,
            'message': f'成功更新 {updated_count} 个资产的状态'
        })
    
    @extend_schema(
        summary="导出资产数据",
        description="导出资产数据为Excel或CSV格式",
        parameters=[
            OpenApiParameter(
                name='format',
                type=OpenApiTypes.STR,
                location=OpenApiParameter.QUERY,
                description='导出格式（excel或csv）',
                default='excel'
            ),
        ],
        tags=['资产管理']
    )
    @action(detail=False, methods=['get'])
    def export(self, request):
        """导出资产数据"""
        export_format = request.query_params.get('format', 'excel')
        queryset = self.get_queryset()
        
        if export_format == 'excel':
            return self._export_excel(queryset)
        elif export_format == 'csv':
            return self._export_csv(queryset)
        else:
            return Response({
                'error': '不支持的导出格式'
            }, status=status.HTTP_400_BAD_REQUEST)
    
    def _export_excel(self, queryset):
        """导出Excel格式"""
        import openpyxl
        from django.http import HttpResponse
        from io import BytesIO
        
        wb = openpyxl.Workbook()
        ws = wb.active
        ws.title = "资产列表"
        
        # 表头
        headers = ['资产名称', '资产编号', '类别', '部门', '状态', '购买价格', '购买日期']
        ws.append(headers)
        
        # 数据
        for asset in queryset:
            ws.append([
                asset.name,
                asset.asset_number,
                asset.category.name if asset.category else '',
                asset.department.name if asset.department else '',
                asset.get_status_display(),
                float(asset.purchase_price or 0),
                asset.purchase_date.strftime('%Y-%m-%d') if asset.purchase_date else ''
            ])
        
        # 保存到内存
        output = BytesIO()
        wb.save(output)
        output.seek(0)
        
        # 返回响应
        response = HttpResponse(
            output.getvalue(),
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = 'attachment; filename="assets_export.xlsx"'
        
        return response
    
    def _export_csv(self, queryset):
        """导出CSV格式"""
        import csv
        from django.http import HttpResponse
        
        response = HttpResponse(content_type='text/csv; charset=utf-8')
        response['Content-Disposition'] = 'attachment; filename="assets_export.csv"'
        
        writer = csv.writer(response)
        writer.writerow(['资产名称', '资产编号', '类别', '部门', '状态', '购买价格', '购买日期'])
        
        for asset in queryset:
            writer.writerow([
                asset.name,
                asset.asset_number,
                asset.category.name if asset.category else '',
                asset.department.name if asset.department else '',
                asset.get_status_display(),
                float(asset.purchase_price or 0),
                asset.purchase_date.strftime('%Y-%m-%d') if asset.purchase_date else ''
            ])
        
        return response


@extend_schema_view(
    list=extend_schema(
        summary="获取维修记录列表",
        description="获取维修记录列表，支持分页、搜索、过滤和排序",
        tags=['维修管理']
    ),
    create=extend_schema(
        summary="创建维修记录",
        description="创建一个新的维修记录",
        tags=['维修管理']
    ),
    retrieve=extend_schema(
        summary="获取维修记录详情",
        description="根据ID获取维修记录的详细信息",
        tags=['维修管理']
    ),
)
class EnhancedMaintenanceViewSet(viewsets.ModelViewSet):
    """增强的维修记录API视图集"""
    
    queryset = MaintenanceRecord.objects.select_related('asset', 'assigned_to').all()
    serializer_class = MaintenanceRecordSerializer
    permission_classes = [permissions.IsAuthenticated]
    authentication_classes = [TokenAuthentication, SessionAuthentication]
    throttle_classes = [CustomUserRateThrottle]
    
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['status', 'maintenance_type', 'asset']
    search_fields = ['description', 'asset__name', 'asset__asset_number']
    ordering_fields = ['created_at', 'scheduled_date', 'completed_at']
    ordering = ['-created_at']


@extend_schema_view(
    list=extend_schema(
        summary="获取耗材列表",
        description="获取耗材列表，支持分页、搜索、过滤和排序",
        tags=['库存管理']
    ),
)
class EnhancedConsumableViewSet(viewsets.ModelViewSet):
    """增强的耗材API视图集"""
    
    queryset = Consumable.objects.select_related('warehouse').all()
    serializer_class = ConsumableSerializer
    permission_classes = [permissions.IsAuthenticated]
    authentication_classes = [TokenAuthentication, SessionAuthentication]
    throttle_classes = [CustomUserRateThrottle]
    
    filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
    filterset_fields = ['warehouse']
    search_fields = ['name', 'description']
    ordering_fields = ['name', 'quantity', 'unit_price']
    ordering = ['name']
    
    @extend_schema(
        summary="获取低库存耗材",
        description="获取库存量低于最小库存的耗材列表",
        tags=['库存管理']
    )
    @action(detail=False, methods=['get'])
    def low_stock(self, request):
        """获取低库存耗材"""
        low_stock_items = self.get_queryset().filter(quantity__lte=models.F('min_quantity'))
        serializer = self.get_serializer(low_stock_items, many=True)
        return Response(serializer.data)


# API版本管理
class APIVersionMiddleware:
    """API版本管理中间件"""
    
    def __init__(self, get_response):
        self.get_response = get_response
    
    def __call__(self, request):
        # 从请求头或URL参数中获取API版本
        api_version = request.META.get('HTTP_API_VERSION') or request.GET.get('version', 'v1')
        request.api_version = api_version
        
        response = self.get_response(request)
        
        # 在响应头中添加API版本信息
        response['API-Version'] = api_version
        response['API-Supported-Versions'] = 'v1, v2'
        
        return response


# API监控和统计
class APIMonitoringMiddleware:
    """API监控中间件"""
    
    def __init__(self, get_response):
        self.get_response = get_response
    
    def __call__(self, request):
        import time
        
        # 记录请求开始时间
        start_time = time.time()
        
        # 处理请求
        response = self.get_response(request)
        
        # 计算响应时间
        response_time = time.time() - start_time
        
        # 记录API调用日志
        if request.path.startswith('/api/'):
            self._log_api_call(request, response, response_time)
        
        return response
    
    def _log_api_call(self, request, response, response_time):
        """记录API调用日志"""
        try:
            from .models_system import SystemLog
            
            SystemLog.objects.create(
                level='INFO',
                message=f'API调用: {request.method} {request.path}',
                details={
                    'method': request.method,
                    'path': request.path,
                    'user': request.user.username if request.user.is_authenticated else 'anonymous',
                    'status_code': response.status_code,
                    'response_time': response_time,
                    'user_agent': request.META.get('HTTP_USER_AGENT', ''),
                    'ip_address': self._get_client_ip(request),
                }
            )
        except Exception as e:
            logger.error(f"记录API调用日志失败: {e}")
    
    def _get_client_ip(self, request):
        """获取客户端IP地址"""
        x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
        if x_forwarded_for:
            ip = x_forwarded_for.split(',')[0]
        else:
            ip = request.META.get('REMOTE_ADDR')
        return ip